/*

 * IndexedDictionaryAdapter.java
 *
 * Copyright(c) 2010
 * Michael Kroez
 * kroez@studiorutton.de
 *
 * All rights reserved.
 *
 * $Id$
 * 
 */

package de.studiorutton.gerengdic.indexeddictionary;

import java.text.ParseException;
import java.util.ArrayList;

import android.graphics.drawable.Drawable;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.RelativeLayout;
import android.widget.TextView;

import de.studiorutton.colorschemes.IColorSchemeMapper;
import de.studiorutton.gerengdic.Prefs;
import de.studiorutton.gerengdic.R;
import de.studiorutton.gerengdic.databaseaccess.ContentAccess;
import de.studiorutton.gerengdic.databaseaccess.DatabaseAccess;
import de.studiorutton.gerengdic.databaseaccess.DatabaseAccessException;
import de.studiorutton.gerengdic.databaseaccess.DatabaseAccess.ViewRecord;
import de.studiorutton.gerengdic.databaseaccess.records.IndexPositionRecord;
import de.studiorutton.gerengdic.dictionary.records.LeftRightValuesRecord;

public class IndexedDictionaryAdapter extends BaseAdapter {
	private static final String TAG = "learningwords";
	private IndexedDictionary id;
	private IIndexedDictionaryView idl;
	private DatabaseAccess da;
	private ArrayList<ViewRecord> viewRecords;
	private int maxArrayListSize = 300;
	private int indexSearched;

	private int VIEW_TYPE_COUNT = 3;

	private int addRecordBlock = 25;
	private int waterMark = 5; // is 1/5
	private int lastPosition = 0;

	public IndexedDictionaryAdapter(IIndexedDictionaryView idl,
			IndexedDictionary id, DatabaseAccess da) {
		// Log.d(TAG, "IndexedDictionaryAdapter: creating.");
		this.idl = idl;
		this.id = id;
		this.da = da;
		viewRecords = new ArrayList<ViewRecord>();

	}

	@Override
	public int getViewTypeCount() {
		return VIEW_TYPE_COUNT;
	}

	@Override
	public int getItemViewType(int position) {
		if (viewRecords.size() == 0)
			return 0;
		return viewRecords.get(position).contentType;
	}

	public boolean isLastInResults(int position) {
		if (position == getCount() - 1)
			return true;
		else if (getItemViewType(position + 1) == ViewRecord.CONTENT_KEY)
			return true;
		else
			return false;
	}

	public int getIndexSearched() {
		return indexSearched;
	}

	public void initialFill() throws DatabaseAccessException {
		viewRecords.clear();

		IndexPositionRecord lastIPR = da.getLastIPRBackward();
		int startOffsetBackward = lastIPR.getViewOffset();
		int crrIndexBackward = 1;
		// Log.d(TAG, "ID: initialFill.");

		ViewRecord vrBackward = null;
		while (crrIndexBackward < (maxArrayListSize / 2) + 1) {
			// Log.d(TAG, "initialFill:backward item="
			// + (startOffsetBackward - crrIndexBackward));
			vrBackward = da.getViewRecordBackwardIterativ(startOffsetBackward
					- crrIndexBackward, id.getLanguage());
			if (vrBackward == null) {
				// Log.d( TAG,
				// "Initialfill backward: Break at crrIndexBackward " +
				// crrIndexBackward );
				break;
			}
			// Log.d(TAG, "initialFill:item=" + vrBackward.content + " type="
			// + vrBackward.contentType);
			viewRecords.add(0, vrBackward);
			crrIndexBackward++;
		}

		indexSearched = crrIndexBackward - 1; // -1 for offset correction

		lastIPR = da.getLastIPRForward();
		int startOffsetForward = lastIPR.getViewOffset();
		int crrIndexForward = 0;
		ViewRecord vrForward = null;

		while (crrIndexForward < maxArrayListSize / 2) {
			// Log.d(TAG, "initialFill:forward item="
			// + (startOffsetForward + crrIndexForward));

			vrForward = da.getViewRecordForwardIterativ(startOffsetForward
					+ crrIndexForward, id.getLanguage());
			if (vrForward == null) {
				// Log.d( TAG, "Initialfill forward: Break at crrIndexForward "
				// + crrIndexForward );
				break;
			}
			// Log.d(TAG, "initialFill:item=" + vrForward.content + " type="
			// + vrForward.contentType);

			// Log.d(TAG, "crrIndexForward = " + crrIndexForward + " Content = "
			// + vrForward.content);
			viewRecords.add(vrForward);
			crrIndexForward++;
		}
		// Log.d(TAG, "viewRecords.size = " + viewRecords.size());
	}

	public View getView(int position, View convertView, ViewGroup parent) {
		// Log.d(TAG, "IndexedDictionaryAdapter: getView " + position + ".");
		//
		// if (lastPosition > position) {
		// Log.d(TAG, "Scrolling backward with " + (lastPosition - position));
		// } else {
		// Log.d(TAG, "Scrolling forward with " + (position - lastPosition));
		// }
		lastPosition = position;

		// if (position <= (maxArrayListSize / waterMark) && position >= 0 &&
		// (lastPosition > position )) {
		// prependRecord(addRecordBlock);
		// position += addRecordBlock;
		// } else if (position > (maxArrayListSize - (maxArrayListSize /
		// waterMark))
		// && position < (maxArrayListSize + 2) && (lastPosition < position)) {
		// appendRecord(addRecordBlock);
		// position -= addRecordBlock;
		// }

		LinearLayout ll = null;

		if (convertView == null) {
			ll = (LinearLayout) LayoutInflater.from(idl.getContext()).inflate(
					R.layout.dictionaryitem, parent, false);
		} else {
			ll = (LinearLayout) convertView;
			// Log.d(TAG,
			// "IndexedDictionaryAdapter: LL childcount is " +
			// ll.getChildCount()
			// + ".");
		}

		ViewRecord vr = viewRecords.get(position);
		LinearLayout llItem = (LinearLayout) ll.findViewById(R.id.searchitem);
		if (vr.contentType == ViewRecord.CONTENT_KEY) {
			createIndexView(vr, llItem);
		} else if (vr.contentType == ViewRecord.CONTENT_RECORD) {
			createRecordView(vr, llItem, position);
		}

		return ll;
	}

	public void createIndexView(ViewRecord vr, LinearLayout ll) {
		IColorSchemeMapper csmi = Prefs.getInstance().getColorSchemeMapper();

		RelativeLayout rl;
		if (ll.getChildCount() == 0) {
			rl = (RelativeLayout) LayoutInflater.from(idl.getContext())
					.inflate(R.layout.indexeddictionaryitemtitle, ll, false);
			rl.setBackgroundDrawable(csmi.getResultTitleBackground());
			ll.addView( rl );
		} else {
			rl = (RelativeLayout) ll.findViewById(R.id.itemtitle);
		}

		TextView tv = (TextView) rl.findViewById(R.id.text);
		tv.setText(vr.content);
		tv.setTextColor(csmi.getResultTitleTextcolor());

		ImageView iv = (ImageView) rl.findViewById(R.id.arrow);
		iv.setImageDrawable(csmi.getResultTitleArrow());

	}

	public void createRecordView(ViewRecord vr, LinearLayout ll, int position) {
		IColorSchemeMapper csmi = Prefs.getInstance().getColorSchemeMapper();

		LeftRightValuesRecord lrvr = null;
		try {
			lrvr = LeftRightValuesRecord.parseDictionaryLine(vr.content);
		} catch (ParseException e) {
			// Log.d(TAG, "getView: parseexception");
			ll.removeAllViews();
			return;
		}
		int maxSubRow = Math.min(lrvr.getLeftValuesSize(),
				lrvr.getRightValuesSize());
		// Log.d(TAG, "IndexedDictionaryAdapter: maxSubRow=" + maxSubRow +
		// ".");
		ll.removeAllViews();
		int crrChild = 0;
		int crrSubRow = 0;
		while (crrSubRow < maxSubRow) {
			RelativeLayout crrLayout;

			// if ( crrChild < ll.getChildCount() ) {
			// crrLayout = (RelativeLayout) ll.getChildAt( crrChild);
			// } else {
			crrLayout = (RelativeLayout) LayoutInflater.from(idl.getContext())
					.inflate(R.layout.dictionaryitemrow, ll, false);
			ll.addView(crrLayout);
			// }

			TextView searchItemLeft = (TextView) crrLayout
					.findViewById(R.id.itemleft);
			TextView searchItemRight = (TextView) crrLayout
					.findViewById(R.id.itemright);

			if (id.getLanguage() == ContentAccess.LANGUAGE_LEFT) {
				searchItemLeft.setText(lrvr.getLeftNthValue(crrSubRow));
				searchItemRight.setText(lrvr.getRightNthValue(crrSubRow));
			} else {
				searchItemLeft.setText(lrvr.getRightNthValue(crrSubRow));
				searchItemRight.setText(lrvr.getLeftNthValue(crrSubRow));
			}

			searchItemLeft.setTextSize(16);
			searchItemRight.setTextSize(16);
			searchItemLeft.setTextColor(csmi.getResultContentTextcolor());
			searchItemRight.setTextColor(csmi.getResultContentTextcolor());

			if (crrChild > 0) {
				TextView dotLeft = (TextView) crrLayout
						.findViewById(R.id.dotleft);
				dotLeft.setText("●");
				dotLeft.setTextColor(csmi.getResultContentTextcolor());
				TextView dotRight = (TextView) crrLayout
						.findViewById(R.id.dotright);
				dotRight.setText("●");
				dotRight.setTextColor(csmi.getResultContentTextcolor());
			}

			crrSubRow++;
			crrChild++;
		}

		int crrRemoveChild = ll.getChildCount() - 1;
		int firstEmptyChild = crrChild;
		while (crrRemoveChild >= firstEmptyChild) {
			ll.removeViewAt(crrRemoveChild);
			crrRemoveChild--;
		}

		ll.setBackgroundDrawable(csmi
				.getResultContentBackground(isLastInResults(position)));
	}

	public void prependRecord(int addBlockSize) {
		int startOffsetBackward = viewRecords.get(0).index;
		int i = 0;
		// Log.d(TAG, "ID: prepending Records. with offset=" +
		// startOffsetBackward);

		while (i < addBlockSize) {
			ViewRecord vrBackward = null;
			try {
				vrBackward = da.getViewRecordBackwardIterativ(
						startOffsetBackward - i, id.getLanguage());
			} catch (DatabaseAccessException e) {
				// Log.d(TAG, e.getLocalizedMessage());
			}
			viewRecords.remove(viewRecords.size() - 1);
			viewRecords.add(0, vrBackward);
			i++;
		}
		notifyDataSetChanged();
	}

	public void appendRecord(int addBlockSize) {
		int i = 0;
		int startOffsetForward = viewRecords.get(viewRecords.size() - 1).index;
		// Log.d(TAG, "ID: appending Records. with offset=" +
		// startOffsetForward);

		while (i < addBlockSize) {
			ViewRecord vrForward = null;
			try {
				vrForward = da.getViewRecordForwardIterativ(startOffsetForward
						+ i, id.getLanguage());
			} catch (DatabaseAccessException e) {
				// Log.d(TAG, e.getLocalizedMessage());
			}
			viewRecords.remove(0);
			viewRecords.add(vrForward);
			i++;
		}
		notifyDataSetChanged();
	}

	public int getCount() {
		return viewRecords.size();
	}

	public Object getItem(int position) {
		return viewRecords.get(position);
	}

	public long getItemId(int position) {
		return viewRecords.get(position).index;
	}

	public void clear(boolean invalidate) {
		viewRecords.clear();
		if (invalidate) {
			notifyDataSetInvalidated();
		}
	}

}
